package cn.edu.tju.elm.service;

import cn.edu.tju.elm.model.DeliveryAddress;
import cn.edu.tju.core.model.User;
import cn.edu.tju.elm.repository.AddressRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
public class AddressServiceImpl implements AddressService {
    
    private static final Logger logger = LoggerFactory.getLogger(AddressServiceImpl.class);
    
    @Autowired
    private AddressRepository addressRepository;
    
    @Override
    @Transactional
    public DeliveryAddress addAddress(DeliveryAddress address, User currentUser) {
        try {
            logger.info("开始添加地址，用户: {}", currentUser.getUsername());
            
            // 如果是第一个地址，设置为默认地址
            long addressCount = addressRepository.countByCustomer(currentUser);
            if (addressCount == 0) {
                address.setIsDefault(true);
                logger.info("用户首次添加地址，设置为默认地址");
            } else if (address.getIsDefault() == null) {
                address.setIsDefault(false);
            }
            
            // 如果设置为默认地址，取消其他地址的默认状态
            if (Boolean.TRUE.equals(address.getIsDefault())) {
                logger.info("设置新极速时时彩走势图地址为默认地址，取消其他地址的默认状态");
                addressRepository.updateDefaultStatusByCustomer(currentUser, false);
            }
            
            // 保存地址
            DeliveryAddress savedAddress = addressRepository.save(address);
            logger.info("地址添加成功，ID: {}", savedAddress.getId());
            
            return savedAddress;
        } catch (Exception e) {
            logger.error("添加地址失败: {}", e.getMessage(), e);
            throw new RuntimeException("添加地址失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public DeliveryAddress updateAddress(Long id, DeliveryAddress addressDetails, User currentUser) {
        try {
            logger.info("开始更新地址，ID: {}, 用户: {}", id, currentUser.getUsername());
            
            // 获取地址并验证是否属于当前用户
            Optional<DeliveryAddress> addressOpt = addressRepository.findById(id);
            if (addressOpt.isPresent()) {
            	DeliveryAddress address = addressOpt.get();
                if (!address.getCustomer().getId().equals(currentUser.getId())) {
                    logger.warn("用户无权修改此地址，用户ID: {}, 地址所属用户ID: {}", 
                               currentUser.getId(), address.getCustomer().getId());
                    throw new RuntimeException("无权修改此地址");
                }
                
                // 验证性别
                if (addressDetails.getContactSex() != null && 
                    addressDetails.getContactSex() != 1 && addressDetails.getContactSex() != 2) {
                    logger.warn("性别参数错误: {}", addressDetails.getContactSex());
                    throw new IllegalArgumentException("性别必须为1(男)或2(女)");
                }
                
                // 更新地址信息
                if (addressDetails.getContactName() != null) {
                    address.setContactName(addressDetails.getContactName());
                }
                if (addressDetails.getContactSex() != null) {
                    address.setContactSex(addressDetails.getContactSex());
                }
                if (addressDetails.getContactTel() != null) {
                    address.setContactTel(addressDetails.getContactTel());
                }
                if (addressDetails.getAddress() != null) {
                    address.setAddress(addressDetails.getAddress());
                }
                
                // 处理默认地址设置
                if (addressDetails.getIsDefault() != null) {
                    if (Boolean.TRUE.equals(addressDetails.getIsDefault())) {
                        // 设置为默认地址，取消其他地址的默认状态
                        logger.info("更新地址为默认地址");
                        setDefaultAddress(id, currentUser);
                        return addressRepository.findById(id).get(); // 返回更新后的地址
                    } else {
                        // 取消默认地址
                        address.setIsDefault(false);
                        logger.info("取消地址的默认状态");
                    }
                }
                
                // 更新时间和更新人
                address.setUpdater(currentUser.getId());
                address.setUpdateTime(LocalDateTime.now());
                
                // 保存更新
                DeliveryAddress updatedAddress = addressRepository.save(address);
                logger.info("地址更新成功，ID: {}", updatedAddress.getId());
                
                return updatedAddress;
            } else {
                logger.warn("地址不存在，ID: {}", id);
                throw new RuntimeException("地址不存在");
            }
        } catch (IllegalArgumentException e) {
            logger.error("参数错误: {}", e.getMessage());
            throw e;
        } catch (RuntimeException e) {
            if (e.getMessage().contains("无权") || e.getMessage().contains("不存在")) {
                logger.error("更新地址失败: {}", e.getMessage());
                throw e;
            }
            logger.error("更新地址失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新地址失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("更新地址失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新地址失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public void deleteAddress(Long id, User currentUser) {
        try {
            logger.info("开始删除地址，极速时时彩走势图ID: {}, 用户: {}", id, currentUser.getUsername());
            
            // 获取地址并验证是否属于当前用户
            Optional<DeliveryAddress> addressOpt = addressRepository.findById(id);
            if (addressOpt.isPresent()) {
            	DeliveryAddress address = addressOpt.get();
                if (!address.getCustomer().getId().equals(currentUser.getId())) {
                    logger.warn("用户无权删除此地址，用户ID: {}, 地址所属用户ID: {}", 
                               currentUser.getId(), address.getCustomer().getId());
                    throw new RuntimeException("无权删除此地址");
                }
                
                // 如果是默认地址，需要设置新的默认地址
                if (Boolean.TRUE.equals(address.getIsDefault())) {
                    logger.info("删除默认地址，尝试设置新的默认地址");
                    List<DeliveryAddress> userAddresses = addressRepository.findByCustomer(currentUser);
                    userAddresses.removeIf(a -> a.getId().equals(id)); // 移除要删除的地址
                    
                    if (!userAddresses.isEmpty()) {
                        // 设置第一个地址为默认地址
                    	DeliveryAddress newDefault = userAddresses.get(0);
                        newDefault.setIsDefault(true);
                        addressRepository.save(newDefault);
                        logger.info("已设置新的默认地址，ID: {}", newDefault.getId());
                    } else {
                        logger.info("用户没有其他地址，无需设置新默认地址");
                    }
                }
                
                // 删除地址
                addressRepository.deleteById(id);
                logger.info("地址删除成功，ID: {}", id);
            } else {
                logger.warn("地址不存在，极速时时彩走势图ID: {}", id);
                throw new RuntimeException("地址不存在");
            }
        } catch (RuntimeException e) {
            logger.error("删除地址失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("删除地址失败: {}", e.getMessage(), e);
            throw new RuntimeException("删除地址失败: " + e.getMessage());
        }
    }
    
    @Override
    public Optional<DeliveryAddress> findById(Long id) {
        return addressRepository.findById(id);
    }
    
    @Override
    public List<DeliveryAddress> findByCustomer(User customer) {
        return addressRepository.findByCustomer(customer);
    }
    
    @Override
    public Optional<DeliveryAddress> findDefaultByCustomer(User customer) {
        return addressRepository.findDefaultAddressByCustomer(customer);
    }
    
    @Override
    public DeliveryAddress save(DeliveryAddress address) {
        return addressRepository.save(address);
    }
    
    @Override
    public void deleteById(Long id) {
        addressRepository.deleteById(id);
    }
    
    @Override
    @Transactional
    public DeliveryAddress setDefaultAddress(Long addressId, User customer) {
        try {
            logger.info("开始设置默认地址，地址ID: {}, 用户: {}", addressId, customer.getUsername());
            
            // 验证地址属于当前用户
            if (!addressRepository.existsByIdAndCustomer(addressId, customer)) {
                logger.warn("地址不存在或不属于当前用户，地址ID: {}, 用户ID: {}", addressId, customer.getId());
                throw new RuntimeException("地址不存在或不属于当前用户");
            }
            
            // 取消所有地址的默认状态
            addressRepository.updateDefaultStatusByCustomer(customer, false);
            logger.info("已取消所有地址的默认状态");
            
            // 设置指定地址为默认
            DeliveryAddress address = addressRepository.findById(addressId)
                    .orElseThrow(() -> new RuntimeException("地址不存在"));
            address.setIsDefault(true);
            
            DeliveryAddress defaultAddress = addressRepository.save(address);
            logger.info("默认地址设置成功，地址ID: {}", addressId);
            
            return defaultAddress;
        } catch (RuntimeException e) {
            logger.error("设置默认地址失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("设置默认地址失败: {}", e.getMessage(), e);
            throw new RuntimeException("设置默认地址失败: " + e.getMessage());
        }
    }
    
    @Override
    public boolean belongsToUser(Long addressId, User customer) {
        return addressRepository.existsByIdAndCustomer(addressId, customer);
    }
    
    @Override
    public long countByCustomer(User customer) {
        return addressRepository.countByCustomer(customer);
    }
    
    @Override
    public boolean existsByIdAndCustomer(Long id, User customer) {
        return addressRepository.existsByIdAndCustomer(id, customer);
    }
    
    @Override
    public List<DeliveryAddress> findByCustomerOrderByCreateTimeDesc(User customer) {
        return addressRepository.findByCustomerOrderByCreateTimeDesc(customer);
    }
}